<template>
  <div class="node-container">
    <div
      v-show="!showContent && !isRoot"
      class="empty-wrapper"
      :style="{ width: columnWidth }"
    />
    <div
      v-show="showContent || isRoot"
      class="node-content"
      :style="{ width: columnWidth, 'align-items': isRoot ? 'flex-start' : 'center', flex: columnWidth ? 'none' : 'auto' }"
    >
      <div
        v-if="isRoot"
        class="expand-icon-wrapper base-btn"
        @click="toggleExpand"
      >
        <a-icon
          v-if="showContent"
          type="minus-circle"
        />
        <a-icon
          v-else
          type="plus-circle"
        />
      </div>
      <a-checkbox
        ref="originCheckbox"
        v-model="nodeData.checked"
        :indeterminate="nodeData.indeterminate"
        :disabled="nodeData.disabled"
        @change="handleChange"

      >
      {{ nodeData.name }}
      </a-checkbox>
    </div>
    <!-- 真正的子级节点 -->
    <div
      v-if="nodeData.children && nodeData.deepth < maxDeep && !validateChildIsBtn(nodeData)"
      v-show="showContent"
      class="node-child"
    >
      <Node
        v-for="(child, index) in nodeData.children"
        ref="nodeChild"
        :key="index"
        :maxDeep="maxDeep"
        :columns-width="columnsWidth"
        :node-data="child"
        :show-content="showContent"
        @childChecked="$emit('childChecked', $event)"
      />
    </div>
    <!-- 对按钮层级的节点需要特殊处理，放在一个容器内 -->
    <div
      v-if="nodeData.children && nodeData.deepth < maxDeep && validateChildIsBtn(nodeData)"
      v-show="showContent"
      class="node-child node-child-btn-wrapper"
    >
      <div
        v-for="(btnChild, index) in nodeData.children"
        :key="index"
        class="btn-item"
      >
        <a-checkbox
          v-model="btnChild.checked"
          :indeterminate="btnChild.indeterminate"
          :disabled="nodeData.disabled"
          @change="handleBtnChildChange(btnChild)"
        >
          {{ btnChild.name }}
        </a-checkbox>
      </div>
    </div>
    <!-- 没有足够多的子级时，填充的空节点 -->
    <div
      v-if="!nodeData.children && nodeData.deepth < maxDeep"
      class="node-child"
    >
      <Node
        ref="nodeChild"
        :maxDeep="maxDeep"
        :columns-width="columnsWidth"
        :node-data="{ deepth: nodeData.deepth + 1 }"
        :show-content="false"
        @childChecked="$emit('childChecked', $event)"
      />
    </div>
    <!-- 收起时展示的子级 -->
    <div
      v-show="nodeData.children && !showContent && nodeData.deepth < maxDeep"
      class="node-child"
    >
      <Node
        v-if="nodeData.children"
        ref="nodeChild"
        :maxDeep="maxDeep"
        :columns-width="columnsWidth"
        :node-data="nodeData.children[0]"
        :show-content="showContent"
        @childChecked="$emit('childChecked', $event)"
      />
    </div>
  </div>
</template>

<script>
export default {
  name: 'Node',
  props: {
    nodeData: {
      type: Object,
      default() {
        return {}
      },
    },
    // 是否展示内容，控制展开、收起的内容显示
    showContent: {
      type: Boolean,
      default: true,
    },
    // 最大的递归深度
    maxDeep: {
      type: Number,
      default: 4
    },
    // 列宽的数组， eg: ['100px', '200px']
    columnsWidth: {
      type: Array,
      default() {
        return []
      }
    }
  },
  data() {
    return {
      isExpand: false,
    }
  },
  computed: {
    // 是否为根节点
    isRoot() {
      return this.nodeData.deepth === 1
    },
    // 当前节点的列宽
    columnWidth() {
      return this.columnsWidth[this.nodeData.deepth - 1]
    }
  },
  methods: {
    toggleExpand() {
      this.$emit('update:showContent', !this.showContent)
    },
    /**
     * 菜单项的选中事件
     */
    handleChange(e) {
      this.$emit('childChecked', this.nodeData)
    },
    /**
     * 按钮项的选中事件
     */
    handleBtnChildChange(data) {
      this.$emit('childChecked', data)
    },
    /**
     * 检查子级是否为按钮（res_type === '2'）
     */
    validateChildIsBtn(node) {
      if (!node.children) return
      return node.children.every((item) => {
        return item.data.res_type === '2'
      })
    },
  },
}
</script>

<style lang="less" scoped>
@pd-font: 4px;
@border-color: #e8e8e8;
@deep: ~'>>>';
.node-container {
  width: 100%;
  display: flex;
  flex: auto;
  @{deep}.ant-checkbox-disabled + span {
    color: #000000;
  }
  .action-wrapper,
  .node-content,
  .empty-wrapper {
    width: 100%;
  }
  .node-content,
  .empty-wrapper {
    padding: @pd-font 20px;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    border-right: 1px solid @border-color;
    border-bottom: 1px solid @border-color;
  }
  .action-wrapper {
    border-right: 1px solid @border-color;
    border-bottom: 1px solid @border-color;
    display: flex;
    min-height: 20px;
    padding: @pd-font 20px;
    .action-item {
      margin-right: 10px;
    }
  }
  .node-content {
    flex: auto;
  }
  .node-child {
    display: flex;
    flex-direction: column;
    flex: auto;
  }
  .expand-icon-wrapper {
    margin-right: 10px;
    font-size: 18px;
  }
  .node-child-btn-wrapper {
    padding: @pd-font 20px;
    flex-direction: row;
    flex-wrap: wrap;
    border-right: 1px solid @border-color;
    border-bottom: 1px solid @border-color;
    .btn-item {
      margin-right: 10px;
    }
  }
}
</style>
